package com.lt.basic.project.application.service.admin.sys.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lt.basic.project.application.mapper.admin.sys.SysAdminMapper;
import com.lt.basic.project.application.mapper.admin.sys.SysRoleMapper;
import com.lt.basic.project.application.service.admin.sys.ISysPermService;
import com.lt.basic.project.application.service.admin.sys.ISysRoleService;
import com.lt.basic.project.common.core.PageResult;
import com.lt.basic.project.pojo.entity.admin.sys.SysAdmin;
import com.lt.basic.project.pojo.entity.admin.sys.SysRole;
import com.lt.basic.project.pojo.validate.commons.PageValidate;
import com.lt.basic.project.pojo.validate.admin.sys.SysRoleCreateValidate;
import com.lt.basic.project.pojo.validate.admin.sys.SysRoleUpdateValidate;
import com.lt.basic.project.pojo.vo.admin.sys.SysRoleVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

/**
 * 系统角色服务实现类
 */
@Service
public class SysRoleServiceImpl implements ISysRoleService {

    @Resource
    SysAdminMapper sysAdminMapper;

    @Resource
    SysRoleMapper sysRoleMapper;

    @Resource
    ISysPermService iSysPermService;

    /**
     * 角色所有
     *
     * @author fzr
     * @return List<SysRoleVo>
     */
    @Override
    public List<SysRoleVo> all() {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id,name,sort,is_disable,create_time,update_time");
        queryWrapper.orderByDesc(Arrays.asList("sort", "id"));
        List<SysRole> sysRoles = sysRoleMapper.selectList(queryWrapper);

        List<SysRoleVo> list = new ArrayList<>();
        for (SysRole sysRole : sysRoles) {
            SysRoleVo vo = new SysRoleVo();

            vo.setId(sysRole.getId());
            vo.setName(sysRole.getName());
            vo.setSort(sysRole.getSort());
            vo.setIsDisable(sysRole.getIsDisable());
            vo.setCreateTime(sysRole.getCreateTime());
            vo.setUpdateTime(sysRole.getUpdateTime());
            vo.setMember(0);
            vo.setRemark("");
            vo.setMenus(Collections.EMPTY_LIST);
            list.add(vo);
        }

        return list;
    }

    /**
     * 角色列表
     *
     * @author fzr
     * @param pageValidate 参数
     * @return PageResult<SysRoleListVo>
     */
    @Override
    public PageResult<SysRoleVo> list(@Validated PageValidate pageValidate) {
        Integer page  = pageValidate.getPageNo();
        Integer limit = pageValidate.getPageSize();

        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc(Arrays.asList("sort", "id"));

        IPage<SysRole> iPage = sysRoleMapper.selectPage(new Page<>(page, limit), queryWrapper);

        List<SysRoleVo> list = new ArrayList<>();
        for (SysRole sysRole : iPage.getRecords()) {
            SysRoleVo vo = new SysRoleVo();
            BeanUtils.copyProperties(sysRole, vo);

            List<Integer> ids = sysAdminMapper.selectChildrenById(sysRole.getId());
            Integer member = ids.size();

            vo.setMenus(new ArrayList<>());
            vo.setMember(member);
            list.add(vo);
        }

        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
    }

    /**
     * 角色详情
     *
     * @author fzr
     * @param id 主键参数
     * @return SysRole
     */
    @Override
    public SysRoleVo detail(Long id) {
        SysRole sysRole = sysRoleMapper.selectOne(new QueryWrapper<SysRole>()
                .eq("id", id)
                .last("limit 1"));

        Assert.notNull(sysRole, "角色已不存在!");

        List<Long> roleIds = new LinkedList<>();
        roleIds.add(sysRole.getId());

        SysRoleVo vo = new SysRoleVo();
        BeanUtils.copyProperties(sysRole, vo);
        vo.setMember(0);
        vo.setMenus(iSysPermService.selectMenuIdsByRoleId(roleIds));

        return vo;
    }

    /**
     * 新增角色
     *
     * @author fzr
     * @param createValidate 参数
     */
    @Override
    @Transactional
    public void add(SysRoleCreateValidate createValidate) {
        Assert.isNull(sysRoleMapper.selectOne(new QueryWrapper<SysRole>()
                .select("id,name")
                .eq("name", createValidate.getName().trim())
                .last("limit 1")), "角色名称已存在!");

        SysRole model = new SysRole();
        model.setName(createValidate.getName().trim());
        model.setRemark(createValidate.getRemark());
        model.setSort(createValidate.getSort());
        model.setIsDisable(createValidate.getIsDisable());
        model.setCreateTime(new Date());
        model.setUpdateTime(new Date());
        sysRoleMapper.insert(model);
        iSysPermService.batchSaveByMenuIds(model.getId(), createValidate.getMenuIds());
    }

    /**
     * 编辑角色
     *
     * @author fzr
     * @param updateValidate 参数
     */
    @Override
    @Transactional
    public void edit(SysRoleUpdateValidate updateValidate) {
        Assert.notNull(sysRoleMapper.selectOne(new QueryWrapper<SysRole>()
                .select("id,name")
                .eq("id", updateValidate.getId())
                .last("limit 1")), "角色已不存在!");

        Assert.isNull(sysRoleMapper.selectOne(new QueryWrapper<SysRole>()
                .select("id,name")
                .ne("id", updateValidate.getId())
                .eq("name", updateValidate.getName().trim())
                .last("limit 1")), "角色名称已存在!");

        SysRole model = new SysRole();
        model.setId(updateValidate.getId());
        model.setName(updateValidate.getName().trim());
        model.setRemark(updateValidate.getRemark());
        model.setSort(updateValidate.getSort());
        model.setIsDisable(updateValidate.getIsDisable());
        model.setUpdateTime(new Date());
        sysRoleMapper.updateById(model);

        iSysPermService.batchDeleteByRoleId(updateValidate.getId());
        iSysPermService.batchSaveByMenuIds(updateValidate.getId(), updateValidate.getMenuIds());
    }

    /**
     * 删除角色
     *
     * @author fzr
     * @param id 主键参数
     */
    @Override
    @Transactional
    public void del(Long id) {
        Assert.notNull(
                sysRoleMapper.selectOne(new QueryWrapper<SysRole>()
                    .select("id", "name")
                    .eq("id", id)
                    .last("limit 1")),
                "角色已不存在!");

        Assert.isNull(sysAdminMapper.selectOne(new QueryWrapper<SysAdmin>()
                .select("id", "role", "nickname")
                .eq("role", id)
                .eq("is_delete", 0)),
                "角色已被管理员使用,请先移除");

        sysRoleMapper.deleteById(id);
        iSysPermService.batchDeleteByRoleId(id);
    }

}
